package org.novelhibernate.core.transaction;

import java.sql.SQLException;
import java.util.LinkedList;

import org.novelhibernate.exception.InproperDivisionOfSQLException;

/**
 * 
 * Use of nested statement can be greatly helpful in terms of performance
 * for example, considering the following code:
 * <p>
 *  template.beginSpringManagedTransaction(getSessionFactory(), false)
 *          .batchSave(" insert into  *** ", array, false)
 * 		    .setAliasedParameter(0, "x.y")
 * 			.batchUpdate(" update *** ", array, false)
 * 		    .flush();
 * </p>
 * 
 * and
 * 
 * <p>
 *  template.beginSpringManagedTransaction(getSessionFactory(), false)
 * 		    .setAliasedParameter(0, "x.y")
 * 			.setNestedStatement(" update *** ", array)
 * 		    .batchSave(" insert into  *** ", array, true)
 * 		    .flush();
 * </p>
 * 
 * 
 * They both work, however, the later one is more efficient since it executes all statements
 * within one single loop of array, while the first one would loop it twice.
 * 
 * 
 * flush() is optional,  but by using it the used variables can be cleaned immediately, which
 * more likely can be collect by GC soon. 
 * 
 * @author Tao Chen
 *
 */
public interface Transaction {

	public static final int SAVE = 0;

	public static final int UPDATE = 1;

	public static final int DELETE = 2;

	/**
	 * This is normally not called explicitly 
	 */
	public void commit();

	/**
	 * This is normally not called explicitly 
	 */
	public void rollback();
	
	public LinkedList<Object> getResultList();
	
	public void flush();

	public Transaction setPredefinedParameter(int index, Object parameter)
			throws Throwable;

	public Transaction setAliasedParameter(int index, String parameter)
	        throws Throwable;

	public Transaction save(String sql, Object target) throws SQLException,
			Throwable;

	public Transaction batchSave(String sql, Object[] targets, boolean isReversed)
			throws SQLException, Throwable;

	public Transaction update(String sql, Object target)
			throws InproperDivisionOfSQLException, SQLException, Throwable;

	public Transaction batchUpdate(String sql, Object[] targets, boolean isReversed)
			throws InproperDivisionOfSQLException, SQLException, Throwable;

	public Transaction delete(String sql, Object target)
			throws InproperDivisionOfSQLException, SQLException, Throwable;

	public Transaction batchDelete(String sql, Object[] targets, boolean isReversed)
			throws InproperDivisionOfSQLException, SQLException, Throwable;

	public Transaction setNestedStatement(String sql, Object[] targets)
			throws Throwable;

	public Transaction setNestedStatement(String sql, String getAttrLowerState) throws Throwable;

	public Transaction setHigherNestedStatement(String sql, Object[] targets, boolean isReversed)
			throws Throwable;

	public Transaction setHigherNestedStatement(String sql, String getAttrLowerState, boolean isReversed) throws Throwable;
	
	public Transaction setHigherTransitionalStatement() throws Throwable;

}
